#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <chrono>
#include <random>
using namespace std;
using namespace chrono;

/*
    thread_local使用场景

dre是一个全局的default_random_engine对象（全局对象可以是C风格的extern，也可是C++风格的static，
如果在同一个源文件中，则在“代码的上面”）。同时开启多个线程运行，每个线程都需要使用这个全局的dre对象，不同的线程对dre设置不同的seed。但是，
又不能让所有线程同时访问同一个dre，这样dre的seed变来变去，而且无法得到想要的随机值序列。

此时有2个解决方案：

    方案1:
       改变声明dre的地方，把dre从全局对象变为线程的局部变量（比如一个函数中）。
        在线程里面，再通过参数的传递，把dre传到需要它的地方。

    方案2:
     声明dre的地方不变，依然是全局，只要加一个thread_local关键词，其他什么都不用改。

方案1很丑陋，方案2很优雅。

    */
namespace ThreadLearn {
    


thread_local default_random_engine dre;

vector<int> test_dre(int seed)
{
    dre.seed(seed);
    int vecSize = 10;
    vector<int> temp(vecSize);
    for (int i = 0; i < vecSize; ++i)
    {
        temp[i] = dre();
        this_thread::sleep_for(milliseconds(100));
    }
    return temp;
}

bool equal(const vector<int> &v1, const vector<int> &v2)
{
    int size1 = v1.size();
    int size2 = v2.size();
    if (size1 != size2)
        return false;

    for (int i = 0; i < size1; ++i)
    {
        if (v1[i] != v2[i])
            return false;
    }
    return true;
}

int main()
{
    int numThread = 2;
    using returnType = vector<int>;

    future<returnType> future1 = async(test_dre, 0);
    returnType result2 = test_dre(0);
    returnType result1 = future1.get();

    if (equal(result1, result2))
        cout << "they are equal" << endl;
    else
        cout << "they are not equal" << endl;

    return 0;
}

}
